package com.haizhi.etl;

import com.haizhi.enums.CrawlStatus;
import com.haizhi.enums.Province;
import com.haizhi.enums.SearchStatus;
import com.haizhi.gsxt.CrawlSchema;
import com.haizhi.gsxt.ProvinceManage;
import com.haizhi.model.ClueEntity;
import com.haizhi.util.DateUtil;
import com.mongodb.client.model.UpdateOneModel;
import com.mongodb.client.model.UpdateOptions;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bson.Document;

public class JsonProcess {

    private static final Logger logger = LogManager.getLogger(JsonProcess.class);

    //默认省份
    private static final Province DEFAULT_PROVINCE = Province.GSXT;


    /**
     * 企业名称处理
     *
     * @param originCompany 原始企业名称
     * @return 处理后的企业名称
     */
    private static String processCompany(String originCompany) {
        if (StringUtils.isEmpty(originCompany)) {
            return null;
        }

        return originCompany.
                replace("*", "").
                replace("#", "").
                replace("$", "").
                replace("%", "").
                replace("&", "").
                replace("!", "").
                replace(" ", "").trim();
    }

    /**
     * json转mongodb Document
     * 外部线索消息结构, 字段不存在则必须填None，保持统一的对接规格。
     * crawl = {
     * <p>
     * # 省份, 极限情况可能不存在
     * province: xxx or None
     * <p>
     * # 企业名称, 必填
     * company: xxx
     * <p>
     * # 数据来源链接 必填
     * source_url: xxx
     * <p>
     * # 注册号 或者统一社会信用号， 省份字段不存在的情况下根据 这个属性计算省份，网页上有 则必填
     * register_code: xxx or None
     * }
     */
    public static UpdateOneModel<Document> jsonToDocument(ClueEntity clueEntity, String company) {

        if (null == clueEntity) {
            logger.error("传入参数为null");
            return null;
        }

        String inTime = DateUtil.getCurrentTime();
        Document queryDocument = new Document(CrawlSchema.ID, company);
        Document setDocument = new Document(CrawlSchema.IN_TIME, inTime);

        //来源链接信息
        String source_url = clueEntity.getSourceUrl();
        if (StringUtils.isNotEmpty(source_url)) {
            setDocument.append(CrawlSchema.SOURCE_URL, source_url);
        }

        //注册号/统一社会信用号
        String register_code = clueEntity.getRegisterCode();
        if (StringUtils.isNotEmpty(register_code)) {
            setDocument.append(CrawlSchema.REGISTER_CODE, register_code);
        }

        //重置采集标识
        setDocument.append(CrawlSchema.CRAWL_STATUS, CrawlStatus.CRAWL_DETAIL_FAIL);
        setDocument.append(CrawlSchema.SEARCH_STATUS, SearchStatus.SEARCH_LIST_FAIL);
        Document updateDocument = new Document("$set", setDocument);

        //UpdateOptions代表批量更新操作未匹配到查询条件时的动作，默认false，什么都不干，true时表示将一个新的Document插入数据库，他是查询部分和更新部分的结合
        return new UpdateOneModel<>(queryDocument, updateDocument, new UpdateOptions().upsert(true));

    }

    /**
     * 根据注册号计算省份
     *
     * @param register_code 注册号/统一社会信用号
     * @return 省份
     */
    private static String calProvince(String register_code) {
        //如果注册号为空 则直接返回默认省份了
        if (StringUtils.isEmpty(register_code)) {
            return null;
        }

        if (register_code.length() == 15 &&
                ProvinceManage.getProvinceCodeDict().containsKey(register_code.substring(0, 2))) {
            return ProvinceManage.getProvinceCodeDict().get(register_code.substring(0, 2));
        }

        if (register_code.length() == 18 &&
                ProvinceManage.getProvinceCodeDict().containsKey(register_code.substring(2, 4))) {
            return ProvinceManage.getProvinceCodeDict().get(register_code.substring(2, 4));
        }

        if (register_code.length() == 13 &&
                ProvinceManage.getProvinceCodeDict().containsKey(register_code.substring(0, 2))) {
            return ProvinceManage.getProvinceCodeDict().get(register_code.substring(0, 2));
        }

        return null;
    }

    //解析省份信息
    public static String parseProvince(ClueEntity clueEntity) {
        String province = clueEntity.getProvince();
        String register_code = clueEntity.getRegisterCode();

        //如果当前省份在省份列表中 则直接把身份信息返回
        if (ProvinceManage.getProvinceDict().containsKey(province)) {
            return ProvinceManage.getProvinceDict().get(province);
        }

        if (StringUtils.isNotEmpty(province)) {
            logger.error("当前省份字段没有捕获: province = {}", province);
        }


        //根据注册号计算省份
        String calProvince = calProvince(register_code);
        if (StringUtils.isNotEmpty(province)) {
            return calProvince;
        }

        return DEFAULT_PROVINCE.getValue();
    }

    /**
     * 判断是否是车牌号
     *
     * @param str 车牌号字符串
     * @return 返回true or false
     */
    private static boolean isCarNum(String str) {
        if (str.length() > 8) {
            return false;
        }

        //判断数字和 字母是否同时存在
        boolean isDigit = false;
        boolean isChar = false;

        int countDigit = 0;
        int countChar = 0;

        for (int i = 0; i < str.length(); i++) {
            if (Character.isDigit(str.charAt(i))) {
                isDigit = true;
                countDigit += 1;
            }
            if ((str.charAt(i) >= 'A' && str.charAt(i) <= 'Z') || (str.charAt(i) >= 'a' && str.charAt(i) <= 'z')) {
                isChar = true;
                countChar += 1;
            }
        }

        if (!isDigit) {
            return false;
        }

        return (countChar >= 0 && countDigit > 1) || (countChar > 1 && countDigit >= 1);

    }

    /**
     * 解析当前企业信息
     */
    public static String parseCompany(ClueEntity clueEntity) {
        //企业信息
        String company = processCompany(clueEntity.getCompany());
        if (StringUtils.isEmpty(company)) {
            logger.error("schema error: 没有企业字段 - {}", clueEntity);
            return null;
        }

        if (StringUtils.length(company) < 4) {
            logger.error("当前企业名称不符合规范: {} {}", company, company.length());
            return null;
        }

        //判断企业是否是车牌号
        if (isCarNum(company)) {
            logger.error("数据类型错误: 当前企业属于车牌号 - {}", company);
            return null;
        }


        return company;
    }

    public static void main(String[] args) {
        System.out.println("3581C".length());

    }

}
